package com.util;

import com.domainUtil.ImgCheckResult;
import com.domainUtil.Media;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiniu.common.QiniuException;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.DownloadUrl;
import com.qiniu.storage.Region;
import com.qiniu.util.Auth;
import living.com.domain.QiNiuTokenResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;



/**
 * <p>
 * 七牛云文件上传和下载工具类
 * </p>
 *
 * @author 大忽悠
 * @create 2022/2/11 15:39
 */
@Slf4j
@Component
public abstract class QiNiuYunUtils {
    private static final String AccessKey = "xJGpG_Fa6dMvBDnsSe_nF8SP8DSoA2mQypwT0uHD";
    private static final String SecretKey = "ch92UTzzBqnj0783HjULiZBJGtq0_xtye5smvfi_";
    public static final Configuration cfg = new Configuration(Region.region0());
    public static final Auth auth=Auth.create(AccessKey,SecretKey);
    public static final BucketManager bucketManager=new BucketManager(auth,cfg);
    public static final ObjectMapper obejctMapper=new ObjectMapper();
    public static final RestTemplate restTemplate=new RestTemplate();
    /**
     * 对象存储域名
     */
    @Value("${qiNiu.helping.url}")
    public  String URL;
    /**
     * 使用哪个桶存放资源
     */
    @Value("${qiNiu.helping.bucketName}")
    private  String bucketName;
    /**
     * 获取上传凭证
     */
    public String getUpToken(String fileName) {
        return auth.uploadToken(bucketName,fileName);
    }

    /**
     * 删除json数组格式的文件
     * @param picJson
     * @throws QiniuException
     */
    public void deleteFileJson(String picJson) throws QiniuException, JsonProcessingException {
        if(picJson!=null){
            String[] pics =obejctMapper.readValue(picJson, String[].class);
            for (String pic : pics) {
                try{
                    bucketManager.delete(bucketName, pic);
                }
                catch (QiniuException e)
                {
                    log.error("文件删除失败:  "+e.getMessage());
                }
            }
        }
    }


    /**
     * 删除指定文件名的文件
     * @param fileName
     * @throws QiniuException
     */
    public void deleteFile(String fileName) throws QiniuException {
        try{
            bucketManager.delete(bucketName, fileName);
        }catch (Exception e){
            log.error(fileName+"-文件删除失败");
           // throw new IllegalArgumentException(fileName+"文件删除失败");
        }
    }

    /**
     * @return 返回生成的上传凭证
     * @throws Exception
     */
    public QiNiuTokenResult getTokenResult(String filePrefix) throws Exception {
        String fileName = generatorFileName(filePrefix);
        return new QiNiuTokenResult(getUpToken(fileName),fileName);
    }

    /**
     * @param sum
     * @return 一次性返回多张上传凭证
     * @throws Exception
     */
    public List<QiNiuTokenResult> getTokenResults(int sum,File_Type file_type) throws Exception {
        ArrayList<QiNiuTokenResult> qiNiuTokenResults  = new ArrayList<>(sum);
        for (int i = 0; i < sum; i++) {
            String fileName = generatorFileName(file_type.getFilePrefix());
            qiNiuTokenResults.add(new QiNiuTokenResult(getUpToken(fileName),fileName));
        }
        return qiNiuTokenResults;
    }

    /**
     * @return 生成文件名
     */
    public abstract String generatorFileName(String filePrefix);

    /**
     * 获取上传凭证的文件类型
     */
    public static enum File_Type{
        ISSUE_IMG("helping/issue_pics/"),ISSUE_VIDEO("helping/comment_videos/")
        ,COMMENT_IMG("helping/comment_pics/"),COMMENT_VIDEO("helping/comment_videos/");
        public String filePrefix;
        File_Type(String filePrefix) {
            this.filePrefix = filePrefix;
        }

        public String getFilePrefix() {
            return filePrefix;
        }
    }

    /**
     * @return 返回文件前缀
     */
    public String getFilePrefix()
    {
        return URL+"/";
    }

    /**
     * @return 返回对应文件输出流
     */
    public byte[] downLoadFile(String fileKey)
    {
        String filePath=fileKey;
        if(!fileKey.contains(getFilePrefix()))
        {
            filePath=getFilePrefix()+fileKey;
        }
        //下载文件
        return doDownLoadFile(filePath);
    }

    private byte[] doDownLoadFile(String fileUrlPath)
    {
        //用二进制数组来接收图片的二进制流
        ResponseEntity<byte[]> rsp = restTemplate.getForEntity(fileUrlPath, byte[].class);
        log.info("文件下载请求结果状态码：" + rsp.getStatusCode());
        byte[] body = rsp.getBody();
        return body;
    }

    /**
     * @param data 要上传的数据
     * @param descUrl 目标地址
     */
    public ImgCheckResult uploadFile(byte[] data,String descUrl) throws IOException {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
        HttpClient httpclient = HttpClients.createDefault();
        //创建一个post请求
        HttpPost request = new HttpPost(descUrl);
        //设置响应头   （ application/octet-stream：二进制流，不知道下载文件类型）
        request.addHeader("Content-Type", "application/octet-stream");
         //定制提交内容
        request.setEntity(new ByteArrayEntity(data, ContentType.create("image/jpg")));
        //由客户端执行(发送)请求,执行校验
        HttpResponse response = httpclient.execute(request);
        // 从响应模型中获取响应实体
        org.apache.http.HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        //将结果转换为
        ImgCheckResult checkResult = obejctMapper.readValue(result, ImgCheckResult.class);
        return checkResult;
    }
}
